package com.songlanyun.modules.concerns.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.MemberConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.account.entity.AccountEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.concerns.dao.UserConcernDao;
import com.songlanyun.modules.concerns.entity.UserConcern;
import com.songlanyun.modules.concerns.model.ConcernDTO;
import com.songlanyun.modules.concerns.model.ConcernSlimVo;
import com.songlanyun.modules.concerns.model.ConcernStatisticsVo;
import com.songlanyun.modules.concerns.model.ParamsPageReq;
import com.songlanyun.modules.concerns.service.UserConcernService;
import com.songlanyun.modules.exception.MemberException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;


@Service("userConcernService")
public class UserConcernServiceImpl extends ServiceImpl<UserConcernDao, UserConcern> implements UserConcernService {

    @Autowired
    private AccountService accountService;

    @Override
    public UserConcern create(UserConcern entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public UserConcern modify(UserConcern entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.updateById(entity);
        return entity;
    }

    @Override
    public void remove(Long id) {
        this.removeById(id);
    }

    /**
     * 我关注的人
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils myConcernsPage(Map<String, Object> params) {
        IPage<ConcernSlimVo> page = this.baseMapper.myConcernsPage(new Query<ConcernSlimVo>().getPage(params), paramsMapToReq(params));
        return new PageUtils(page);
    }

    /**
     * 我的粉丝列表
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils myFansPage(Map<String, Object> params) {
        IPage<ConcernSlimVo> page = this.baseMapper.myFansPage(new Query<ConcernSlimVo>().getPage(params), paramsMapToReq(params));
        return new PageUtils(page);
    }

    private ParamsPageReq paramsMapToReq(Map<String, Object> params) {
        ParamsPageReq pageReq = new ParamsPageReq();
        Long userId = MapUtil.getLong(params, "user_id");
        if (userId != null && userId > 0) {
            pageReq.setUserId(userId);
        }

        String nickname = MapUtil.getStr(params, "nickname");
        if (StringUtils.isNotBlank(nickname)) {
            pageReq.setNickname(nickname);
        }

        return pageReq;
    }

    /**
     * 关注其它会员
     *
     * @param userId
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public UserConcern concern(Long userId, ConcernDTO dto) {

        if (userId.equals(dto.getConcernedUserId())) {
            throw new RRException(MemberException.CONCERN_SELF);
        }
        AccountEntity concern = accountService.getUserById(userId, true);
        AccountEntity concerned = accountService.getUserById(dto.getConcernedUserId(), true);


        UserConcern userConcern = this.getConcern(concern.getId(), concerned.getId());
        if (userConcern != null) {
            throw new RRException(MemberException.CONCERN_EXISTS);
        }
        userConcern = new UserConcern();
        userConcern.setConcernUserId(concern.getId());
        userConcern.setConcernedUserId(concerned.getId());
        userConcern.setConcernTime(new Date());

        /**
         * 查询他是不是我的粉丝（他关注我没有）
         */
        UserConcern userConcerned = this.getConcern(concerned.getId(), concern.getId());
        if (userConcerned == null) {
            //没有互关
            userConcern.setEachConcern(false);
        } else {
            //互关
            userConcern.setEachConcern(true);
            userConcerned.setEachConcern(true);
            modify(userConcerned);
        }
        create(userConcern);
        return userConcern;
    }

    /**
     * 取消关注
     *
     * @param userId
     * @param dto
     */
    @Transactional
    @Override
    public void cancelConcern(Long userId, ConcernDTO dto) {
        AccountEntity concern = accountService.getUserById(userId, true);
        AccountEntity concerned = accountService.getUserById(dto.getConcernedUserId(), true);

        UserConcern userConcern = this.getConcern(concern.getId(), concerned.getId());
        if (userConcern != null) {
            this.remove(userConcern.getId());
        }

        /**
         * 查询他是不是我的粉丝（他关注我没有）
         */
        UserConcern userConcerned = this.getConcern(concerned.getId(), concern.getId());
        if (userConcerned != null) {
            //取消互关
            userConcerned.setEachConcern(false);
            modify(userConcerned);
        }

    }


    /**
     * 统计我关注的人数与我的粉丝人数
     *
     * @param userId
     * @return
     */
    @Override
    public ConcernStatisticsVo statisticsPerson(Long userId) {

        ConcernStatisticsVo vo = new ConcernStatisticsVo();
        int concernsNum = this.count(new LambdaQueryWrapper<UserConcern>()
                .eq(UserConcern::getConcernUserId, userId));

        int fansNum = this.count(new LambdaQueryWrapper<UserConcern>()
                .eq(UserConcern::getConcernedUserId, userId));
        vo.setConcernNum(concernsNum);
        vo.setFansNum(fansNum);
        return vo;
    }

    @Override
    public Integer countByConcernUserId(Long userId) {
        return null;
    }

    @Override
    public Boolean isConcern(Long userId, Long publisherId) {
        Integer b = this.baseMapper.selectCount(
                new LambdaQueryWrapper<UserConcern>()
                        .eq(UserConcern::getConcernUserId, userId)
                        .eq(UserConcern::getConcernedUserId, publisherId)
        );
        return b > 0;
    }


    /**
     * 查询关注实体
     *
     * @param concernUserId
     * @param concernedUserId
     * @return
     */
    private UserConcern getConcern(Long concernUserId, Long concernedUserId) {
        UserConcern userConcern = this.getOne(new LambdaQueryWrapper<UserConcern>()
                .eq(UserConcern::getConcernUserId, concernUserId)
                .eq(UserConcern::getConcernedUserId, concernedUserId)
                .last("limit 1"));
        return userConcern;
    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        return null;
    }

}